package com.adv.ems.filters.original.before;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.adv.ems.db.entity.CollectPointDO;
import com.adv.ems.db.entity.EnergyDataCumulateDO;
import com.adv.ems.db.entity.EnergyDataProcessDO;
import com.adv.ems.enums.CollectPointDataTypeEnum;
import com.adv.ems.filters.EnergyDataBaseFilter;
import com.adv.ems.filters.dto.FilterParam;
import com.adv.ems.filters.original.dto.EnergyDataOriginalBeforeDTO;
import com.adv.ems.manager.CollectPointManager;
import com.adv.ems.manager.EnergyDataCumulateManager;
import com.adv.ems.manager.EnergyDataProcessManager;
import com.adv.ems.model.vo.ResultVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Component
public class DataRepeatCheckBeforeFilter extends EnergyDataBaseFilter<EnergyDataOriginalBeforeDTO, Boolean> {
    @Resource
    EnergyDataCumulateManager energyDataCumulateManager;
    @Resource
    EnergyDataProcessManager energyDataProcessManager;
    @Resource
    CollectPointManager collectPointManager;

    @Override
    protected String getFilterName() {
        return "原始数据重复校验";
    }

    @Override
    protected double getOrder() {
        return 4;
    }

    @Override
    protected boolean isBefore() {
        return true;
    }

    @Override
    protected String getType() {
        return EnergyDataOriginalBeforeDTO.class.getName();
    }

    @Override
    protected ResultVO<Boolean> handle(FilterParam<EnergyDataOriginalBeforeDTO> param) {
        List<EnergyDataOriginalBeforeDTO> list = param
                .getList()
                .stream()
                .filter(this::cumulate)
                .filter(this::process)
                .collect(Collectors.toList());
        param.setList(list);
        return ResultVO.success();
    }

    private boolean cumulate(EnergyDataOriginalBeforeDTO data) {
        Map<Long, CollectPointDO> pointMap = collectPointManager.getAllMap();
        CollectPointDO point = pointMap.get(data.getCollectPointId());
        if (point == null || point.getDataType() == null) {
            log.error("数据异常，采集点不存在或dataType无效【{}】【{}】", JSONUtil.toJsonStr(data), point);
            return false;
        }
        if (!point.getDataType().equals(CollectPointDataTypeEnum.CUMULATE.name())) {
            return true;
        }
        List<EnergyDataCumulateDO> list = energyDataCumulateManager.getByPointIdAndColDate(data.getCollectPointId(), data.getColDate());
        if (CollectionUtil.isNotEmpty(list)) {
            EnergyDataCumulateDO existed = list.get(0);
            if (existed.getOriValue().equals(data.getColData())) {
                return false;
            }
            log.info("原始数据【id:{}】采集点【{}】上报时间【{}】重复，新值【{}】旧数据【{}】，删除旧数据", data.getId(), point.getId(), data.getColDate(), data.getColData(), JSONUtil.toJsonStr(existed));
            energyDataCumulateManager.deleteColData(existed.getId(), existed.getColDate());
        }
        return true;
    }

    private boolean process(EnergyDataOriginalBeforeDTO data) {
        Map<Long, CollectPointDO> pointMap = collectPointManager.getAllMap();
        CollectPointDO point = pointMap.get(data.getCollectPointId());
        if (point == null || point.getDataType() == null) {
            log.error("数据异常，采集点不存在或dataType无效【{}】【{}】", JSONUtil.toJsonStr(data), point);
            return false;
        }
        if (!point.getDataType().equals(CollectPointDataTypeEnum.PROCESS.name())) {
            return true;
        }
        List<EnergyDataProcessDO> list = energyDataProcessManager.getByPointIdAndColDate(data.getCollectPointId(), data.getColDate());
        if (CollectionUtil.isNotEmpty(list)) {
            EnergyDataProcessDO existed = list.get(0);
            if (existed.getOriValue().equals(data.getColData())) {
                return false;
            }
            log.info("原始数据【id:{}】采集点【{}】上报时间【{}】重复，新值【{}】旧数据【{}】，删除旧数据", data.getId(), point.getId(), data.getColDate(), data.getColData(), JSONUtil.toJsonStr(existed));
            energyDataProcessManager.deleteColData(existed.getId(), existed.getColDate());
        }
        return true;
    }
}
